package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.sixtynine.stock.Constants.CommonData;
import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Company;
import org.sixtynine.stock.entity.CompanyDocument;
import org.sixtynine.stock.entity.User;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.CompanyDocumentService;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.service.file.FileDataService;
import org.sixtynine.stock.service.file.FileDataServiceImpl;
import org.sixtynine.stock.util.FileUtil;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan this class handle daily share data
 */

@Controller
@SessionAttributes
public class CompanyDocumentController extends BackEndAuthController {

	/** TODO configure */
	private int RECORDS_PER_PAGE = 10;

	@Autowired
	private GenericService genericService;

	@Autowired
	private CompanyDocumentService companyDocumentService;

	@Autowired
	private FileDataService fileDataService;

	@Autowired
	DataManagerService dataManagerService;

	@RequestMapping(value = "/admin/companydocument/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria) {
		ModelAndView modelAndView = new ModelAndView(
				"/admin/companydocument/list");
		loadData(1, -1, criteria.getCompanyId(), criteria.getFromDate(),
				criteria.getToDate(), modelAndView, criteria);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/companydocument/add")
	public ModelAndView addCompanyDocument(HttpServletRequest request) {

		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			return modelAndView;
		}

		modelAndView = new ModelAndView("/admin/companydocument/add");
		modelAndView.addObject("companyDocument", new CompanyDocument());
		List<BaseEntity> compaies = dataManagerService
				.getData(CommonData.COMPANY.toString());
		modelAndView.addObject("companyMap", compaies);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/companydocument/add/company_process")
	public ModelAndView addingCompanyDocumentByCompany(
			@ModelAttribute("uploadFile") FileUploadForm uploadFile,
			@RequestParam("company.id") int companyId,
			@RequestParam("date") Date date, @RequestParam("name") String name,
			BindingResult result, HttpServletRequest request) {

		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			// TODO add error message
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}

		// find the company
		Company company = null;
		List<BaseEntity> baseEntities = dataManagerService
				.getData(CommonData.COMPANY.toString());
		for (BaseEntity baseEntity : baseEntities) {
			Company cmp = (Company) baseEntity;
			if (cmp.getId() == companyId) {
				company = cmp;
				break;
			}
		}

		if (company == null) {
			// TODO add error message
			modelAndView = new ModelAndView("/admin/companydocument/add");
			return modelAndView;
		}

		// int companyId = company.getId();

		MultipartFile multipartFile = uploadFile.getFile();
		String orinalFileName = multipartFile.getOriginalFilename();
		String extention = FileUtil.getFileExtention(orinalFileName);

		String uploadFileName = org.sixtynine.stock.util.StringUtil
				.getUniqueKey() + "-" + companyId + "." + extention;

		ReturnData<String> returnData = fileDataService.saveFile(multipartFile,
				FileDataServiceImpl.COMPANY_DOCUMENT, uploadFileName);

		StringBuilder message = new StringBuilder();
		if (returnData._isSuccess()) {

			CompanyDocument companyDocument = new CompanyDocument();
			companyDocument.setCompany(company);
			companyDocument.setDate(date);
			companyDocument.setFileName(uploadFileName);
			companyDocument.setName(name);

			genericService.saveOrUpdate(companyDocument);
			modelAndView = new ModelAndView("/admin/companydocument/list");

			loadData(1, -1, -1, null, null, modelAndView, null);
		} else {
			modelAndView = new ModelAndView("/admin/companydocument/add");
			message.append(uploadFileName);
		}

		modelAndView.addObject("message", message);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/companydocument/list")
	public ModelAndView listOfCompanyDocument(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {

		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			// TODO add error message
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}
		modelAndView = new ModelAndView("/admin/companydocument/list");
		loadData(page, totalRecords, -1, null, null, modelAndView, null);

		return modelAndView;
	}

	/**
	 * load data
	 * 
	 * @param page
	 * @param totalRecords
	 * @param companyId
	 * @param fromDate
	 * @param toDate
	 * @param modelAndView
	 */
	private void loadData(Integer page, Integer totalRecords, int companyId,
			Date fromDate, Date toDate, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		GridPramDTO gridPramDTO = new GridPramDTO();
		gridPramDTO.setRows(RECORDS_PER_PAGE);
		if (page != null) {
			gridPramDTO.setPage(page);
		} else {
			gridPramDTO.setPage(1);
		}
		if (totalRecords != null) {
			gridPramDTO._setTotalNumberOfRecords(totalRecords);
		}

		Page<CompanyDocument> companyDocumentPage = companyDocumentService
				.searchCompanyDocument(companyId, fromDate, toDate, gridPramDTO);
		modelAndView.addObject("companyDocumentPage", companyDocumentPage);

		List<BaseEntity> compaies = dataManagerService
				.getData(CommonData.COMPANY.toString());

		modelAndView.addObject("companyMap", compaies);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();

			criteria.setCompanyId(companyId);
			criteria.setFromDate(fromDate);
			criteria.setToDate(toDate);
		}
		modelAndView.addObject("criteria", criteria);

	}

	@RequestMapping(value = "/admin/companydocument/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editCompanyDocument(HttpServletRequest request,
			@PathVariable Integer id) {
		ModelAndView modelAndView = null;
		if (!isUserLogged(request)) {
			// TODO add error message
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}

		SessionBean sessionBean = SessionBean.getInstance(request);

		modelAndView = new ModelAndView("/admin/companydocument/edit");
		BaseEntity companyDocument = genericService.findById(id,
				CompanyDocument.class);
		modelAndView.addObject("companyDocument", companyDocument);
		List<BaseEntity> compaies = dataManagerService
				.getData(CommonData.COMPANY.toString());
		modelAndView.addObject("companyMap", compaies);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/companydocument/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingCompanyDocument(
			@ModelAttribute CompanyDocument companyDocument,
			@PathVariable Integer id) {

		genericService.saveOrUpdate(companyDocument);
		ModelAndView modelAndView = new ModelAndView(
				"/admin/companydocument/list");
		loadData(1, -1, companyDocument.getCompany().getId(),
				companyDocument.getDate(), companyDocument.getDate(),
				modelAndView, null);

		String message = "Record successfully updated.";
		modelAndView.addObject("message", message);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/companydocument/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteCompanyDocument(@PathVariable Integer id,
			HttpServletRequest request) {

		ModelAndView modelAndView = null;
		if (!isUserLogged(request)) {
			// TODO add error message
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}
		genericService.delete(id, CompanyDocument.class);
		modelAndView = new ModelAndView("/admin/companydocument/list");

		loadData(1, -1, -1, null, null, modelAndView, null);

		String message = "Record successfully deleted.";
		modelAndView.addObject("message", message);
		return modelAndView;
	}

}
